/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sge.Datos;

import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JLabel;
import java.awt.GridLayout;
import java.io.IOException;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author
 */
public class ClienteMySQL extends Conexion {
    private final static Logger logger = Logger.getLogger(ClienteMySQL.class.getName());
    private boolean crearUsuario = false;
    private boolean crearBaseDatos = false;
    private static String llaves[][] = {

//        {"sge", "!aCl4ve"}, //comentar para primer incio
                 {"root", "25428506"}, //descomentar para primer incio
    };
    private final String FILE_DB = "BD_SGE.sql";

    public ClienteMySQL() {
       this("bd_sge"); //comentar para primer incio
        //this("mysql"); //descomentar para primer incio
    }

    public ClienteMySQL(String nbd) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            
            this.URL = "jdbc:mysql://localhost:3306/";
            this.dbName = nbd;
            this.extend = "?zeroDateTimeBehavior=convertToNull"
                    + "&useUnicode=true"
                    + "&autoReconnect=true"
                    + "&characterEncoding=utf8"
                    + "&characterSetResults=utf8"
                    + "&allowMultiQueries=true";
            this.user = llaves[0][0];
            this.password = llaves[0][1];
//            crearUsuario = true; //descomentar para primer incio
//            crearBaseDatos = true; //descomentar para primer incio
            conectar();

        } catch (ClassNotFoundException ex) {
            logger.log(Level.SEVERE,
                    "No se pudo cargar el controlador mysql.jdbc.Driver.", ex);
        }
    }

    @Override
    protected void crearUsuario() {
        if (this.user.equals("root") && this.crearUsuario) {
            crearUsuario(llaves[0][0], llaves[0][1], "ALL", "bd_sge.*");
            this.crearUsuario = false;
            this.user = llaves[0][0];
            this.password = llaves[0][1];
            conectar();
        }
    }

    @Override
    protected void crearBaseDatos() {
        if (this.user.equals("root") && this.crearBaseDatos) {
        //conectarConBaseDatos("mysql");
        try {                
            ejecutarArchivo(this.getClass().getResource(FILE_DB));
        } catch (IOException ex) {
            logger.log(Level.SEVERE,
                    "No se pudo leer el archivo para crear la base de datos", ex);
        }
        }
    }

    @Override
    protected void errorDeConexion(SQLException ex) {
        logger.log(Level.INFO, "Error code: {0}", ex.getErrorCode());
        switch (ex.getErrorCode()) {
            case 0:
                logger.log(Level.WARNING,
                        "No fue posible realizar la conexión con el servidor mysql.", 
                        ex);
                break;
            case 1045:
                logger.log(Level.WARNING,
                        "Usuario 'sge' no existe, se procede a crearlo.");
                crearUsuario = true;
                solicitarAutenticacion();
                break;
            case 1049:
                logger.log(Level.WARNING,
                        "Base de datos 'bd_sge' no existe, se procede a crearla.");
                crearBaseDatos = true;
                solicitarAutenticacion();
                break;
        }
    }

    @Override
    public boolean existeBaseDatos(String dataBase) {
        boolean rt = false;
        consultar("SELECT 1 FROM information_schema.SCHEMATA"
                + " WHERE SCHEMA_NAME = '" + dataBase + "'");
        try {
            rt = rs.next();
        } catch (SQLException ex) {
            logger.log(Level.SEVERE,
                    "No se pudo consultar la lista de bases de datos.", ex);
        }
        return rt;
    }

    @Override
    public void conectarConBaseDatos(String dbName) {
        if (dbName != null && !this.dbName.equals(dbName)) {
            this.dbName = dbName;
            conectar();
        }
    }

    @Override
    protected void finalize() throws Throwable {
        cerrarConexion();
        super.finalize();
    }

    private void crearUsuario(String user, String pass, String priv, String on) {

        ejecutar("CREATE USER " + user + "@localhost");
        ejecutar("GRANT " + priv + " ON " + on + " TO " + user + "@localhost"
                + " IDENTIFIED BY '" + pass + "'");

        ejecutar("CREATE USER " + user + "@127.0.0.1");
        ejecutar("GRANT " + priv + " ON " + on + " TO " + user + "@127.0.0.1"
                + " IDENTIFIED BY '" + pass + "'");

    }

    private void solicitarAutenticacion() {
        JPasswordField fieldPwd = new JPasswordField(20);
        JPanel panel = new JPanel(new GridLayout(4, 1));

        panel.add(new JLabel("Una operación sobre la base de datos necesita obtener permisos de root.",
                JLabel.CENTER));
        panel.add(new JLabel(".: Escriba la clave del usuario "
                + "\"root\" de su servidor MySQL:", JLabel.CENTER));
        panel.add(fieldPwd);
        fieldPwd.requestFocus();
        int opt = JOptionPane.showConfirmDialog(null, panel,
                "Clave de Acceso", JOptionPane.OK_CANCEL_OPTION,
                JOptionPane.QUESTION_MESSAGE);

        switch (opt) {
            case JOptionPane.OK_OPTION:
                user = "root";
                password = new String(fieldPwd.getPassword());
                conectar();
                break;

        }
    }
}
